import { Injectable } from '@nestjs/common';
import { PrismaService } from 'nestjs-prisma';
import { ResponseUtil } from "../../utils/response.util";
import {ImportDataDto, UpdateDto} from "./dto/req-demo.dto";
import {ApiException} from "../../common/exceptions/api.exception";
import {ExcelOptionAll} from "../common/excel/excel.interface";
import {EXCEL_ARR_KRY} from "../common/excel/excel.constant";
import {ExcelTypeEnum} from "../common/excel/excel.enum";
import {specsAddData} from "./dto/demo-item.dto";

@Injectable()
export class SpecsService {
  constructor(
    private readonly prisma: PrismaService
  ) {}

  async findItemById(projectId: Number) {
    try {
      const data = await this.prisma.projectSpecs.findFirst({
        where: { projectId: Number(projectId) },
      });

      return ResponseUtil.success(data);
    } catch (error) {
      return ResponseUtil.error('查询失败', error);
    }
  }

  async update(updateDto: UpdateDto) {
    return await this.prisma.$transaction(async (prisma) => {
      const { id } = updateDto
      const project = await prisma.projectSpecs.findUnique({
        where: {
          id
        }
      })
      if (!project) throw new ApiException('该项目不存在，请刷新后重试。');
      const params = { ...updateDto }
      delete params.id
      delete params.createBy
      delete params.createTime

      return await prisma.projectSpecs.update({
        data: params,
        where: {
          id,
        }
      })
    })
  }


  /* 导入产品列表 */
  async importData(ImportDataDtoArr: ImportDataDto[]) {

    return await this.prisma.$transaction(async (prisma) => {
      // 解析 dto数据
      const importObjArr: ExcelOptionAll[] =
        Reflect.getMetadata(EXCEL_ARR_KRY, ImportDataDto) ?? [];
      const excelData = await this.formatImport(importObjArr);
      const fieldMap = {}
      excelData[1].forEach((item, index) => {
        fieldMap[item] = excelData[0][index]
      })

      for (const item of ImportDataDtoArr) {
        let newData: ImportDataDto = {} as ImportDataDto
        Object.keys(item).forEach((key) => {
          newData[fieldMap[key]] = item[key] || ''
        })

        const specsAddNewData = JSON.parse(JSON.stringify(specsAddData))
        const keys = Object.keys(specsAddNewData)
        const fieldKeys = ['Desc', 'Price', 'Note']

        keys.forEach((key) => {
          if (typeof specsAddNewData[key] === 'object') {
            fieldKeys.forEach(field => {
              const fieldToLow = field.toLowerCase()
              if (specsAddNewData[key].hasOwnProperty(fieldToLow)) {
                specsAddNewData[key][fieldToLow] = newData[`${key}_${field}`]
              }
            })
          } else {
            specsAddNewData[key] = `${newData[key]}`
          }
        })


        const project = await prisma.projectList.findFirst({
          where: {
            projectName: newData.projectName,
          },
        });
        if (project) {
          const specsData = await prisma.projectSpecs.findFirst({
            where: {
              projectId: project.projectId,
            },
          });
          if (specsData) {
            await prisma.projectSpecs.update({
              data: { projectId: project.projectId, ...specsAddNewData},
              where: {
                id: specsData.id,
              }
            })
          }
        }
      }
    });
  }

  private async formatImport(importObjArr: ExcelOptionAll[]): Promise<[][]> {
    const optionArr: ExcelOptionAll[] = importObjArr
      .filter(
        (item) =>
          item.type === ExcelTypeEnum.ALL || item.type === ExcelTypeEnum.IMPORT,
      ) //过滤
      .sort((obj, obj2) => obj.sort - obj2.sort); //排序
    const data = [];
    data.push(optionArr.map((item) => item.propertyKey));
    data.push(optionArr.map((item) => item.name));
    return data;
  }

}
